#include "Skeleton.h"
#include "dataTypes.h"

Skeleton::Skeleton()
{
}

Skeleton::Skeleton(const Skeleton& s)
{
	median = s.median;

	neck = median->GetChild(0)->GetChild(2);
	leftArm = median->GetChild(0)->GetChild(0)->GetChild(0);
	rightArm = median->GetChild(0)->GetChild(1)->GetChild(0);
	leftLeg = median->GetChild(1)->GetChild(0);
	rightLeg = median->GetChild(2)->GetChild(0);
	spine = median->GetChild(0);

	animation = s.animation;
}

Skeleton::~Skeleton()
{
	delete median;
	delete animation;
}

void Skeleton::Build(int aHeight, int aWeight, bool aMale, int aSpeed)
{
	float length = 13.0f + aHeight;
	float width = 3.0f + aWeight;
	float shouldersW = 4.0f;
	if(!aMale) shouldersW = 3.0f;

	median = new Bone();
	spine = median->AddChild(0,length,width*1.75f);

	Bone* leftPelvis = median->AddChild(-PI/2+PI/8,3,width);
	Bone* rightPelvis = median->AddChild(PI/2-PI/8,3,width);
	leftLeg = leftPelvis->AddChild(PI,length,width);
	rightLeg = rightPelvis->AddChild(PI,length,width);

	Bone* leftShoulder = spine->AddChild(-PI/2-PI/16,shouldersW+width/4,width);
	Bone* rightShoulder = spine->AddChild(PI/2+PI/16,shouldersW+width/4,width);
	leftArm = leftShoulder->AddChild(PI+PI/8,length*3/4,width);
	rightArm = rightShoulder->AddChild(PI-PI/8,length*3/4,width);

	neck = spine->AddChild(0,9,width);

	animationSpeed = (float)aSpeed;
	animation = new Animation();
	animation->Build(aSpeed);
}

void Skeleton::AssignKeyFrames(AnimationFrame* aAnimationFrame)
{
	spine->SetKeyFrame(aAnimationFrame->GetKeyFrame(0));
	neck->SetKeyFrame(aAnimationFrame->GetKeyFrame(1));
	leftArm->SetKeyFrame(aAnimationFrame->GetKeyFrame(2));
	rightArm->SetKeyFrame(aAnimationFrame->GetKeyFrame(3));
	leftLeg->SetKeyFrame(aAnimationFrame->GetKeyFrame(4));
	rightLeg->SetKeyFrame(aAnimationFrame->GetKeyFrame(5));
}

void Skeleton::StartAnimation(int aAnimation)
{
	AssignKeyFrames(animation->GetFrame(aAnimation));
}

void Skeleton::StopAnimation()
{
	spine->SetKeyFrame(animation->GetFrame(ANIMATION_NONE)->GetKeyFrame(0));
	neck->SetKeyFrame(animation->GetFrame(ANIMATION_NONE)->GetKeyFrame(1));
	leftArm->SetKeyFrame(animation->GetFrame(ANIMATION_NONE)->GetKeyFrame(2));
	rightArm->SetKeyFrame(animation->GetFrame(ANIMATION_NONE)->GetKeyFrame(3));
	leftLeg->SetKeyFrame(animation->GetFrame(ANIMATION_NONE)->GetKeyFrame(4));
	rightLeg->SetKeyFrame(animation->GetFrame(ANIMATION_NONE)->GetKeyFrame(5));
}

void Skeleton::Tick()
{
	median->Tick();
}

void Skeleton::Dump(Bone* aBone)
{
	if(aBone == NULL)
	{
		aBone = median;
		printf("\nSkeleton dump:\n");
	}

	printf("Bone: a:%f, l:%f, x:%f, y:%f, jx:%f, jy:%f, c:%d\n",aBone->GetAngle(),aBone->GetLength()
																							 ,aBone->GetX(),aBone->GetY()
																							 ,aBone->GetJointX(), aBone->GetJointY()
																							 ,aBone->GetChildCount());

	for(int i=0; i<aBone->GetChildCount(); i++) Dump(aBone->GetChild(i));
}